package edu.the.last.audio;

import java.util.Arrays;

import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Soundbank;
import javax.sound.midi.Synthesizer;

import edu.the.last.Messages;
import edu.the.last.modell.Music;
/**
 * This class is responsible for playing the chords during the play back.
 * @author albertcsani
 *
 */
public class PlayChord extends Thread {
	private Synthesizer synth; // the music synthesizer
	private Soundbank soundbank; // the sound bank
	private MidiChannel[] channels; // all the channels
	private MidiChannel channel;
	private Boolean tick = true;
	private int interval;
	private int volume;
	private String chords[];
	private String chordPrim[] = { Messages.getString("PlayChord.0"), Messages.getString("PlayChord.1"), Messages.getString("PlayChord.2"), Messages.getString("PlayChord.3"), Messages.getString("PlayChord.4"), Messages.getString("PlayChord.5"), Messages.getString("PlayChord.6"), Messages.getString("PlayChord.7"), Messages.getString("PlayChord.8"), Messages.getString("PlayChord.9"), Messages.getString("PlayChord.10"), Messages.getString("PlayChord.11"), Messages.getString("PlayChord.12"), Messages.getString("PlayChord.13"), Messages.getString("PlayChord.14"), Messages.getString("PlayChord.15"), Messages.getString("PlayChord.16"), Messages.getString("PlayChord.17"), Messages.getString("PlayChord.18"), Messages.getString("PlayChord.19"), Messages.getString("PlayChord.20"), Messages.getString("PlayChord.21"), Messages.getString("PlayChord.22"), Messages.getString("PlayChord.23") }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$ //$NON-NLS-14$ //$NON-NLS-15$ //$NON-NLS-16$ //$NON-NLS-17$ //$NON-NLS-18$ //$NON-NLS-19$ //$NON-NLS-20$ //$NON-NLS-21$ //$NON-NLS-22$ //$NON-NLS-23$ //$NON-NLS-24$

	// bar=utem, beat ?= negyed

	/**
	 * tries to create a synthesizer and get an instrument and channel
	 * 
	 * @param chords
	 *            the chords to play
	 * @param bpm
	 *            beat per minute
	 * @param bpb
	 *            beat per bar
	 * @param volume
	 *            volume of the chords
	 */
	public PlayChord(Music music, int volume) {
		this.chords = Arrays.copyOf(music.getChords(), music.getChords().length);
		interval = 60 * 1000 / music.getBpm() * music.getBpb();
		this.volume = volume;
		try {
			synth = MidiSystem.getSynthesizer();
			synth.open();
			soundbank = synth.getDefaultSoundbank();
			if (soundbank != null)
				synth.loadAllInstruments(soundbank);
			channels = synth.getChannels();
			channel = channels[0];
			channel.programChange(5); // Electric Piano
		} catch (Exception e) {
			System.out.println(e);
		}
	}

	/**
	 * Stops the playing
	 */
	public void stopChords() {
		tick = false;
	}
/**
 * plays one chord
 * @param chord the chord to play
 */
	private void playChord(String chord) {
		int ind = 0;
		for (int i = 0; i < chordPrim.length; i++) {
			if (chordPrim[i].equals(chord)) {
				ind = i;
			}
		}
		int prime = 60 + ind;
		int terc = prime + 4;
		if (ind > 11) {
			prime = 60 + ind - 12;
			terc = prime + 3;
		}
		int quint = prime + 7;
		try {
			channel.noteOn(prime, volume);
			channel.noteOn(terc, volume);
			channel.noteOn(quint, volume);
			Thread.currentThread();
			Thread.sleep(interval);
			channel.noteOff(prime, volume);
			channel.noteOff(terc, volume);
			channel.noteOff(quint, volume);
		} catch (InterruptedException e) {
		}
	}
/**
 * sets the volume of the chords
 * @param volume 1-120
 */
	public void setVolume(int volume) {
		this.volume = volume;
	}
/**
 * play the chords
 */
	public void run() {
		tick = true;

		for (int i = 0; i < chords.length && tick; i++) {
			playChord(chords[i]);
		}
	}
}
